<template>
	<view class="app-components-fold">
		<view class="app-components-fold__body" :animation="animationData">
			<view :id="elId" ref="bodyRef">
				<slot></slot>
			</view>
		</view>
		<view @tap.stop="expandedChange">
			<slot name="foot" :expanded="expanded">
				<view class="app-components-fold__foot e-p-t-20 e-p-b-20 e-flex-xy-center" >
					<text class="c-secondary e-font-22">{{ $t(expanded ? downText : upText) }}</text>
					<view class="app-components-fold__icon" :class="[expanded ? 'is-down' : 'is-up']">
						<e-icon :name="icon" size="28rpx"></e-icon>
					</view>
				</view>
			</slot>
		</view>
		
	</view>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { nanoid, getRect, getNvueRect } from '@/common/utils';
import { useCurrentInstance } from '@/common/hooks';

const props = defineProps({
	upText: {
		type: String,
		default: 'common.foldOpen'
	},
	downText: {
		type: String,
		default: 'common.foldClose'
	},
	icon: {
		type: String,
		default: 'arrow-down'
	},
	duration: {
		type: [String, Number],
		default: 300
	}
});

const ctx = useCurrentInstance();

const elId = ref(nanoid(21, true));
const bodyRef = ref(null);
const expanded = ref(false);

// 查询内容高度
const queryRect = () => {
	return new Promise((resolve) => {
		// #ifndef APP-NVUE
		getRect(ctx, `#${elId.value}`).then((size) => {
			resolve(size);
		});
		// #endif
		// #ifdef APP-NVUE
		getNvueRect(bodyRef.value).then((size) => {
			resolve(size);
		});
		// #endif
	});
};
const animationData = ref({});

let animating = false;
const expandedChange = async () => {
	if (animating) return;
	expanded.value = !expanded.value;
	// 每次面板打开或者收起时，都查询元素尺寸获得最新的高度
	const rect = await queryRect();
	const height = expanded.value ? rect.height : 0;
	animating = true;
	const animation = uni.createAnimation({
		timingFunction: 'ease-in-out'
	});
	animation
		.height(height)
		.step({
			duration: props.duration
		})
		.step();
	// 导出动画数据给面板的animationData值
	animationData.value = animation.export();
	// 标识动画结束
	setTimeout(() => {
		animating = false;
	}, props.duration);
};
</script>

<style lang="scss" scoped>
@include appBem_b(components-fold) {
	@include appBem_e(body) {
		height: 0;
		transition: height 0.5s;
		overflow: hidden;
	}

	@include appBem_e(icon) {
		transition: transform 0.2s;

		@include appWhen(up) {
			transform: rotate(0);
		}

		@include appWhen(down) {
			transform: rotate(180deg);
		}
	}
}
</style>
